﻿using Cl.Model.DataBaseEntityDtos.Goods.BaseGoods;
using Cl.Model.DataBaseEntityDtos.Orders.GoodsOrders;
using Cl.Model.Results;
using Cl.Utils.Helper;
using Cl.Utils.Primitives.Const.Goods;
using Cl.Utils;
using NetTaste;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cl.Utils.Helper.AutoMap;
using Cl.Entity.DataBaseEntity.Orders;
using Cl.Repository;
using Cl.Service.Service.System.UploadFile;
using NetTopologySuite.Simplify;
using Cl.Model.DataBaseEntityDtos.Shops.BaseShop;
using SqlSugar;
using Microsoft.IdentityModel.Tokens;

namespace Cl.Service.Service.Orders.GoodsOrders
{
    public class GoodsOrderService : IGoodsOrderService
    {

        private readonly ClRepository<GoodsOrder> GoodsOrderRepository;
        private readonly IFileService FileService;
        private readonly ClRepository<GoodsOrderRelatedGoods> GoodsOrderRelatedGoodsRepository;
        public GoodsOrderService(ClRepository<GoodsOrder> goodsOrderRepository, IFileService fileService,
            ClRepository<GoodsOrderRelatedGoods> goodsOrderRelatedGoodsRepository)
        {
            GoodsOrderRepository = goodsOrderRepository;
            FileService = fileService;
            GoodsOrderRelatedGoodsRepository = goodsOrderRelatedGoodsRepository;
        }


        public async Task<PageResultModel<GoodsOrderOutputDto>> Query(SearchGoodsOrderDto request)
        {
            RefAsync<int> total = 0;
            var response = new PageResultModel<GoodsOrderOutputDto>
            {
                Result = new List<GoodsOrderOutputDto>()
            };

            var sql = GoodsOrderRepository.AsQueryable()
                .Includes(rog => rog.OrderRelatedGoodsList, good => good.BaseGoodsData)
                .Includes(c => c.CreateUser)
                .Includes(up => up.UpdateUser);

            sql.WhereIF(request.Status != null && request.Status != 0, x => x.Status == request.Status);

            sql.OrderBy(p => p.CreateTime, OrderByType.Desc);
            // 计算开始和结束索引
            List<GoodsOrder> list;
            if (request.IsPage)
            {
                list = await sql.ToPageListAsync(request.PageIndex, request.PageSize, total);
            }
            else
            {
                list = await sql.ToListAsync();
                total = list.Count;
            }

            response.TotalCount = total;
            response.Result = list.Select(x => new GoodsOrderOutputDto(x) { }).ToList();

            return response;

        }

        public async Task<ResultInfoModel> CreateOrder(GoodsOrderInputDto value)
        {
            try
            {
                if (value == null)
                    return GetResult.Error("参数不能null");

                //数据准备
                var operationData = value.MapTo<GoodsOrderInputDto, GoodsOrder>();
                operationData.OrderCode = "M" + GenerateSerialNumber();
                operationData.CreateId = GlobalUserManager.UserId;
                operationData.CreateTime = DateTime.Now;
                operationData.Community = string.Empty;
                operationData.Avatar = string.Empty;
                operationData.Status = 2;
                operationData.UserName = string.Empty;
                operationData.UserPhone = string.Empty;
                operationData.UserAddress = string.Empty;
                operationData.ExpirationData = DateTime.Now.AddMinutes(10);
                operationData.PayType = string.Empty;
                operationData.PayNo = string.Empty;
                operationData.PayTime = DateTime.Now;
                var result = await GoodsOrderRepository.AsInsertable(operationData).ExecuteReturnEntityAsync();
                if (result.Id != 0)
                {
                    List<GoodsOrderRelatedGoods> relatedList = new List<GoodsOrderRelatedGoods>();
                    foreach (var item in value.GoodsIds)
                    {
                        relatedList.Add(new GoodsOrderRelatedGoods() { OrderId = result.Id, GoodsId = item });
                    }
                    await GoodsOrderRelatedGoodsRepository.AsInsertable(relatedList).ExecuteCommandAsync();

                    return GetResult.Success(string.Empty, operationData.OrderCode);
                }
                return GetResult.Error("操作失败");
            }
            catch (Exception ex)
            {
                LoggerHelper.TryCatch(ex);
                return GetResult.Error(ex.Message);
            }


            static string GenerateSerialNumber()
            {
                Random random = new Random();
                StringBuilder randNoSb = new StringBuilder();
                string dateStr = DateTime.Now.ToString("yyyyMMdd");
                int randomNumber = random.Next(1000, 10000); // Generates a number between 1000 and 9999

                randNoSb.Append(dateStr).Append(randomNumber);
                return randNoSb.ToString();
            }
        }

        public async Task<GoodsOrderOutputDto> FindOrder(string orderCode)
        {
            GoodsOrderOutputDto? result = null;
            var obj = await GoodsOrderRepository.AsQueryable()
                .Where(x => x.OrderCode == orderCode).FirstAsync();
            if (obj != null)
                result = new GoodsOrderOutputDto(obj) { };
            return result;
        }

        public async Task<ResultInfoModel> PayOrder(PayOrderInputDto value)
        {
            if (value == null)
                return GetResult.Error("参数不能null");
            var result = await GoodsOrderRepository
                .AsUpdateable(new GoodsOrder()
                {
                    PayNo = value.PayNo,
                    PayType = value.PayType,
                    PayTime = DateTime.Now,
                    Status = 3
                })
                .UpdateColumns(it => new { it.PayNo, it.PayType, it.PayTime, it.Status })
                .Where(x => x.OrderCode == value.OrderCode)
                .ExecuteCommandAsync();
            if (result > 0)
            {
                return GetResult.Success();
            }
            return GetResult.Error("操作失败");

        }



    }
}
